<!DOCTYPE html>
<html lang="en"><head><title></title><script>
    /**
     * Factory method to create and load a BotGuardClient instance.
     * @param options - Configuration options for the BotGuardClient.
     * @returns A promise that resolves to a loaded BotGuardClient instance.
     */
    function loadBotGuard(challengeData) {
      this.vm = this[challengeData.globalName];
      this.program = challengeData.program;
      this.vmFunctions = {};
      this.syncSnapshotFunction = null;

      if (!this.vm)
        throw new Error('[BotGuardClient]: VM not found in the global object');

      if (!this.vm.a)
        throw new Error('[BotGuardClient]: Could not load program');

      const vmFunctionsCallback = function (
        asyncSnapshotFunction,
        shutdownFunction,
        passEventFunction,
        checkCameraFunction
      ) {
        this.vmFunctions = {
          asyncSnapshotFunction: asyncSnapshotFunction,
          shutdownFunction: shutdownFunction,
          passEventFunction: passEventFunction,
          checkCameraFunction: checkCameraFunction
        };
      };

      this.syncSnapshotFunction = this.vm.a(this.program, vmFunctionsCallback, true, this.userInteractionElement, function () {/** no-op */ }, [ [], [] ])[0]

      // an asynchronous function runs in the background and it will eventually call
      // `vmFunctionsCallback`, however we need to manually tell JavaScript to pass
      // control to the things running in the background by interrupting this async
      // function in any way, e.g. with a delay of 1ms. The loop is most probably not
      // needed but is there just because.
      return new Promise(function (resolve, reject) {
        i = 0
        refreshIntervalId = setInterval(function () {
          if (!!this.vmFunctions.asyncSnapshotFunction) {
            resolve(this)
            clearInterval(refreshIntervalId);
          }
          if (i >= 10000) {
            reject("asyncSnapshotFunction is null even after 10 seconds")
            clearInterval(refreshIntervalId);
          }
          i += 1;
        }, 1);
      })
    }

    /**
     * Takes a snapshot asynchronously.
     * @returns The snapshot result.
     * @example
     * ```ts
     * const result = await botguard.snapshot({
     *   contentBinding: {
     *     c: "a=6&a2=10&b=SZWDwKVIuixOp7Y4euGTgwckbJA&c=1729143849&d=1&t=7200&c1a=1&c6a=1&c6b=1&hh=HrMb5mRWTyxGJphDr0nW2Oxonh0_wl2BDqWuLHyeKLo",
     *     e: "ENGAGEMENT_TYPE_VIDEO_LIKE",
     *     encryptedVideoId: "P-vC09ZJcnM"
     *    }
     * });
     *
     * console.log(result);
     * ```
     */
    function snapshot(args) {
      return new Promise(function (resolve, reject) {
        if (!this.vmFunctions.asyncSnapshotFunction)
          return reject(new Error('[BotGuardClient]: Async snapshot function not found'));

        this.vmFunctions.asyncSnapshotFunction(function (response) { resolve(response) }, [
          args.contentBinding,
          args.signedTimestamp,
          args.webPoSignalOutput,
          args.skipPrivacyBuffer
        ]);
      });
    }

    function runBotGuard(challengeData) {
      const interpreterJavascript = challengeData.interpreterJavascript.privateDoNotAccessOrElseSafeScriptWrappedValue;

      if (interpreterJavascript) {
        new Function(interpreterJavascript)();
      } else throw new Error('Could not load VM');

      const webPoSignalOutput = [];
      return loadBotGuard({
        globalName: challengeData.globalName,
        globalObj: this,
        program: challengeData.program
      }).then(function (botguard) {
        return botguard.snapshot({ webPoSignalOutput: webPoSignalOutput })
      }).then(function (botguardResponse) {
        return { webPoSignalOutput: webPoSignalOutput, botguardResponse: botguardResponse }
      })
    }

    function obtainPoToken(webPoSignalOutput, integrityToken, identifier) {
      const getMinter = webPoSignalOutput[0];

      if (!getMinter)
        throw new Error('PMD:Undefined');

      const mintCallback = getMinter(integrityToken);

      if (!(mintCallback instanceof Function))
        throw new Error('APF:Failed');

      const result = mintCallback(identifier);

      if (!result)
        throw new Error('YNJ:Undefined');

      if (!(result instanceof Uint8Array))
        throw new Error('ODM:Invalid');

      return result;
    }
</script></head><body></body></html>